<?php

namespace App\Logic;

use \Common\Logic\BaseLogic;

class WxLogic extends BaseLogic
{
    public static $wxOpenUrl = "https://open.weixin.qq.com";
    public static $wxApiUrl = "https://api.weixin.qq.com";

    private $wxdicModel;


    public function __construct()
    {
        parent::__construct();
        $this->wxdicModel = D('Wxdic');
    }

    /**
     * 获取微信授权url
     * @param $redirectUri
     * @return string
     */
    public function getOauthUrl($redirectUri)
    {
        $url = static::$wxOpenUrl . "/connect/oauth2/authorize?";
        $url .= http_build_query(array(
            "appid" => C('WX.appId'),
            "redirect_uri" => $redirectUri,
            "response_type" => "code",
            "scope" => "snsapi_userinfo",
            "state" => 1
        ));
        $url .= '#wechat_redirect';
        return $url;
    }

    /**
     * 获取微信凭证
     * @param $code
     * @param string $state
     * @return mixed
     */
    public function getAccessToken($code, $state = '')
    {
        if (empty($code)) {
            return static::$res->err("微信code不能为空");
        }
        $url = static::$wxApiUrl . "/sns/oauth2/access_token";
        $param = array(
            "appid" => C('WX.appId'),
            "secret" => C('WX.appSecret'),
            "code" => $code,
            "grant_type" => "authorization_code"
        );

        $info = curl($url, $param, false);
        $accessToken = $info['access_token'];
        $openId = $info['openid'];
        if (empty($accessToken) || empty($openId)) {
            return static::$res->err("微信凭证获取失败");
        }

        return static::$res->suc("成功", array(
            "openId" => $openId,
            "accessToken" => $accessToken
        ));
    }

    /**
     * 拉取微信用户信息
     * @param $openId
     * @param $accessToken
     * @param string $lang
     * @return mixed
     */
    public function getUserInfo($openId, $accessToken, $lang = "zh_CN")
    {
        if (empty($openId)) {
            return static::$res->err("openId不能为空");
        }

        if (empty($accessToken)) {
            return static::$res->err("accessToken不能为空");
        }

        $url = static::$wxApiUrl . "/sns/userinfo?";
        $param = array(
            "access_token" => $accessToken,
            "openid" => $openId,
            "lang" => $lang
        );

        $info = curl($url, $param, false);
        if (empty($info['openid'])) {
            return static::$res->err("用户信息获取失败");
        }

        return static::$res->suc("成功", $info);
    }

    /**
     * 获取api调用的accessAoken
     */
    public function getApiAccessToken()
    {
        $dicName = "accessToken";
        $appId = C('WX.appId');
        $accessToken = $this->getWxdic($dicName, $appId);
        if (!empty($accessToken)) {
            return static::$res->suc("成功", $accessToken);
        }

        $url = static::$wxApiUrl . "/cgi-bin/token";
        $param = array(
            "appid" => $appId,
            "secret" => C('WX.appSecret'),
            "grant_type" => "client_credential"
        );

        $info = curl($url, $param, false);

        $accessToken = $info['access_token'];
        if (empty($accessToken)) {
            return static::$res->err("微信token获取失败");
        }

        $this->setWxdic($dicName, $appId, $accessToken);
        return static::$res->suc("成功", $accessToken);
    }

    /**
     * 获取微信jsticket
     * @return mixed
     */
    public function getJsApiTicket()
    {
        $dicName = "jsApiTicket";
        $appId = C('WX.appId');
        $ticket = $this->getWxdic($dicName, $appId);
        if (!empty($ticket)) {
            return static::$res->suc("成功", $ticket);
        }

        $accessTokenRes = $this->getApiAccessToken();
        if (static::$res->isErr($accessTokenRes)) {
            return $accessTokenRes;
        }
        $accessToken = $accessTokenRes['Result'];

        $url = static::$wxApiUrl . "/cgi-bin/ticket/getticket";
        $param = array(
            "access_token" => $accessToken,
            "type" => "jsapi"
        );

        $info = curl($url, $param, false);
        $ticket = $info['ticket'];
        if (empty($ticket)) {
            return static::$res->err("微信");
        }

        $this->setWxdic($dicName, $appId, $ticket);
        return static::$res->suc("成功", $ticket);
    }

    /**
     * 获取微信js配置
     * @param string $url
     * @return mixed
     */
    public function getJsApiConf($url = "")
    {
        if (empty($url)) {
            return static::$res->err("调用地址不能为空");
        }
        $ticketRes = $this->getJsApiTicket();
        if (static::$res->isErr($ticketRes)) {
            return $ticketRes;
        }
        $ticket = $ticketRes['Result'];

        $timestamp = time();
        $nonceStr = createNoncestr();

        $signatureStr = "jsapi_ticket=$ticket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        $signature = sha1($signatureStr);

        $config = array(
            "appId" => C('WX.appId'),
            "timestamp" => $timestamp,
            "nonceStr" => $nonceStr,
            "signature" => $signature
        );

        return static::$res->suc("成功", $config);
    }

    /**
     * 保存微信证明图片到本地
     * @param $mediaId
     * @return mixed
     */
    public function saveProofImg($mediaId)
    {
        $imgRes = $this->getWxImg($mediaId);
        if (static::$res->isErr($imgRes)) {
            return static::$res->err($imgRes['Message']);
        }

        $imgInfo = $imgRes['Result'];

        $imageUri = "/ImgFile/UserProofPhoto/" . date("Ymd") . "/" . time() . "_" . rand(1111, 9999) . '.jpg';
        $fileName = WEB_PATH . $imageUri;
        if (!saveImg(base64_encode($imgInfo['body']), $fileName)) {
            return static::$res->err("微信图片转存失败");
        }

        $photoUri = "/taskSys" . $imageUri;
        return static::$res->suc("成功", $photoUri);
    }
    
    /**
     * 获取微信API
     *
     * @return void
     */
    public function getWxApi()
    {
        require_once(WEB_PATH.'/Application/Common/Vendor/WechatHelper/WechatPhpSdk/Api.class.php');
        require_once(WEB_PATH.'/Application/Common/Vendor/WechatHelper/WechatPhpSdk/Utils/HttpCurl.class.php');
        require_once(WEB_PATH.'/Application/Common/Vendor/WechatHelper/WechatPhpSdk/Utils/Error.class.php');
        require_once(WEB_PATH.'/Application/Common/Vendor/WechatHelper/WechatPhpSdk/Utils/SHA1.class.php');
        require_once(WEB_PATH.'/Application/Common/Vendor/WechatHelper/WechatPhpSdk/Utils/Xml.class.php');

        
        $api = new \Gaoming13\WechatPhpSdk\Api(
            array(
                'appId' => C('WX.appId'),
                'appSecret' => C('WX.appSecret'),
                'get_access_token' => function () {
                    $wxLogic = A('App/Wx', 'Logic');
                    $accessTokenRes = $wxLogic->getApiAccessToken();
                    return json_encode(array(
                        "access_token" => $accessTokenRes['Result'],
                        "expires_in" => time() + 7200
                    ));
                },
                'save_access_token' => function ($token) {
                    $fileName = RUNTIME_PATH . 'Logs/wechat/' . date('Y-m-d') . '.log';
                    logs($token, $fileName);
                }
            )
        );
        return $api;
    }
    
    /**
     * 获取微信临时二维码
     *
     * @param [type] $scene_id
     * @return void
     */
    public function getQcodeUrl($scene_id)
    {
        $api=$this->getWxApi();
        list($err, $data) = $api->create_qrcode($scene_id, 60*60*24*7); //创建一个临时二维码，有效期2天
        //打印$err,$data
        if (empty($data)) {
            //生产失败
            return '';
        }
        return $data->url;
        //var_dump($data);
        //返回微信信息 参数为ticket
        //$api->get_qrcode_url('gQH58DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xLzQweUctT2psME1lcEJPYWJkbUswAAIEApzVVQMEZAAAAA==');
    }

    /**
     * 获取微信字典
     * @param $name
     * @param $belong
     * @return mixed
     */
    private function getWxdic($name, $belong)
    {
        $where = array(
            "belong" => $belong,
            "name" => $name,
            "expires" => array("GT", date('Y-m-d H:i:s'))
        );

        return $this->wxdicModel->where($where)->getField("val");
    }


    /**
     * 设置微信字典
     * @param $name
     * @param $belong
     * @param $val
     */
    private function setWxdic($name, $belong, $val)
    {
        $where = array(
            "belong" => $belong,
            "name" => $name,
        );

        $expires = date("Y-m-d H:i:s", time() + 6600);

        if ($this->wxdicModel->where($where)->count()) {
            $data = array(
                "val" => $val,
                "expires" => $expires
            );
            $this->wxdicModel->where($where)->save($data);
        } else {
            $data = array_merge($where, array(
                "val" => $val,
                "expires" => $expires
            ));
            $this->wxdicModel->add($data);
        }
    }

    /**
     * 获取微信图像
     * @param $mediaId
     * @return mixed
     */
    private function getWxImg($mediaId)
    {
        if (empty($mediaId)) {
            return static::$res->err("微信图像ID不能为空");
        }

        $accessTokenRes = $this->getApiAccessToken();
        if (static::$res->isErr($accessTokenRes)) {
            return $accessTokenRes;
        }
        $accessToken = $accessTokenRes['Result'];

        $url = static::$wxApiUrl . "/cgi-bin/media/get?access_token=$accessToken&media_id=$mediaId";

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEARDER, 0);
        curl_setopt($ch, CURLOPT_NOBODY, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $package = curl_exec($ch);
        $httpInfo = curl_getinfo($ch);
        curl_close($ch);

        if (empty($package) || empty($httpInfo)) {
            return static::$res->err("微信图像获取失败");
        }

        $imgAll = array_merge(array("header" => $httpInfo), array("body" => $package));
        return static::$res->suc("成功", $imgAll);
    }
}
